package com.sys.exception;

import com.alibaba.fastjson.JSONObject;
import com.sys.utils.Utils;
import com.bhudy.exception.SysException;
import com.bhudy.exception.SysExceptionCode;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.EOFException;
import java.io.IOException;
import java.text.ParseException;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author com.bhudy
 * @Description 全局异常拦截器
 * @Date 2019-10-30 23:09:37
 */
@ControllerAdvice
@ResponseBody
public class SysExceptionHandler {

    //运行时异常
    @ExceptionHandler(RuntimeException.class)
    public String runtimeExceptionHandler(RuntimeException ex) {
        return resultFormat(SysExceptionCode.CODE_20001.getCode(), ex);
    }

    //空指针异常
    @ExceptionHandler(NullPointerException.class)
    public String nullPointerExceptionHandler(NullPointerException ex) {
        return resultFormat(SysExceptionCode.CODE_20002.getCode(), ex);
    }

    //类型转换异常
    @ExceptionHandler(ClassCastException.class)
    public String classCastExceptionHandler(ClassCastException ex) {
        return resultFormat(SysExceptionCode.CODE_20003.getCode(), ex);
    }

    //IO异常
    @ExceptionHandler(IOException.class)
    public String iOExceptionHandler(IOException ex) {
        return resultFormat(SysExceptionCode.CODE_20004.getCode(), ex);
    }

    //未知方法异常
    @ExceptionHandler(NoSuchMethodException.class)
    public String noSuchMethodExceptionHandler(NoSuchMethodException ex) {
        return resultFormat(SysExceptionCode.CODE_20005.getCode(), ex);
    }

    //数组越界异常
    @ExceptionHandler(IndexOutOfBoundsException.class)
    public String indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex) {
        return resultFormat(SysExceptionCode.CODE_20006.getCode(), ex);
    }

    //400错误
    @ExceptionHandler({HttpMessageNotReadableException.class})
    public String requestNotReadable(HttpMessageNotReadableException ex) {
        return resultFormat(SysExceptionCode.CODE_20007.getCode(), ex);
    }

    //400错误
    @ExceptionHandler({TypeMismatchException.class})
    public String requestTypeMismatch(TypeMismatchException ex) {
        return resultFormat(SysExceptionCode.CODE_20008.getCode(), ex);
    }

    //400错误
    @ExceptionHandler({MissingServletRequestParameterException.class})
    public String requestMissingServletRequest(MissingServletRequestParameterException ex) {
        return resultFormat(SysExceptionCode.CODE_20009.getCode(), ex);
    }

    //405错误
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public String request405(HttpRequestMethodNotSupportedException ex) {
        return resultFormat(SysExceptionCode.CODE_20010.getCode(), ex);
    }

    //406错误
    @ExceptionHandler({HttpMediaTypeNotAcceptableException.class})
    public String request406(HttpMediaTypeNotAcceptableException ex) {
        return resultFormat(SysExceptionCode.CODE_20011.getCode(), ex);
    }

    //500错误
    @ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
    public String server500(RuntimeException ex) {
        return resultFormat(SysExceptionCode.CODE_20012.getCode(), ex);
    }

    //栈溢出
    @ExceptionHandler({StackOverflowError.class})
    public String requestStackOverflow(StackOverflowError ex) {
        return resultFormat(SysExceptionCode.CODE_20013.getCode(), ex);
    }

    //算术条件异常
    @ExceptionHandler({ArithmeticException.class})
    public String arithmeticException(ArithmeticException ex) {
        return resultFormat(SysExceptionCode.CODE_20014.getCode(), ex);
    }

    //数字格式化异常
    @ExceptionHandler({NumberFormatException.class})
    public String numberFormatException(NumberFormatException ex) {
        return resultFormat(SysExceptionCode.CODE_20015.getCode(), ex);
    }

    //解析异常
    @ExceptionHandler({ParseException.class})
    public String parseException(ParseException ex) {
        return resultFormat(SysExceptionCode.CODE_20016.getCode(), ex);
    }

    //文件已结束异常
    @ExceptionHandler({EOFException.class})
    public String arithmeticExecption(EOFException ex) {
        return resultFormat(SysExceptionCode.CODE_20017.getCode(), ex);
    }

    //自定义错误
    @ExceptionHandler({SysException.class})
    public String sysException(SysException ex) {
        return resultFormat(ex.getCode(), ex);
    }

    //其他错误
    @ExceptionHandler({Exception.class})
    public String exception(Exception ex) {
        return resultFormat(SysExceptionCode.CODE_40005.getCode(), ex);
    }

    private <T extends Throwable> String resultFormat(Integer code, T ex) {
        Utils.loggerError(getClass(), ex);

        Map map = new HashMap();
        map.put("code", code);
        String message = SysExceptionCode.getMessage(code);
        if (message == null || message.equals("")) {
            map.put("message", ex.getMessage() == null ? "null" : ex.getMessage());
        } else {
            map.put("message", message);
        }
        return JSONObject.toJSONString(map);
    }

}